527d13
@@ -282,7 +282,7 @@
public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx procCtx,
 
           // evaluate filter expression and update statistics
           long newNumRows = evaluateExpression(parentStats, pred, aspCtx,
-              neededCols, fop, 0);
+              neededCols, fop, parentStats.getNumRows());
           Statistics st = parentStats.clone();
 
           if (satisfyPrecondition(parentStats)) {
@@ -320,13 +320,13 @@
public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx procCtx,
 
     protected long evaluateExpression(Statistics stats, ExprNodeDesc pred,
         AnnotateStatsProcCtx aspCtx, List<String> neededCols,
-        Operator<?> op, long evaluatedRowCount) throws CloneNotSupportedException, SemanticException {
+        Operator<?> op, long currNumRows) throws CloneNotSupportedException, SemanticException {
       long newNumRows = 0;
       Statistics andStats = null;
 
-      if (stats.getNumRows() <= 1 || stats.getDataSize() <= 0) {
+      if (currNumRows <= 1 || stats.getDataSize() <= 0) {
         if (LOG.isDebugEnabled()) {
-          LOG.debug("Estimating row count for " + pred + " Original num rows: " + stats.getNumRows() +
+          LOG.debug("Estimating row count for " + pred + " Original num rows: " + currNumRows +
               " Original data size: " + stats.getDataSize() + " New num rows: 1");
         }
         return 1;
@@ -342,41 +342,40 @@
protected long evaluateExpression(Statistics stats, ExprNodeDesc pred,
           aspCtx.setAndExprStats(andStats);
 
           // evaluate children
+          long evaluatedRowCount = currNumRows;
           for (ExprNodeDesc child : genFunc.getChildren()) {
-            newNumRows = evaluateChildExpr(aspCtx.getAndExprStats(), child,
+            evaluatedRowCount = evaluateChildExpr(aspCtx.getAndExprStats(), child,
                 aspCtx, neededCols, op, evaluatedRowCount);
-            if (satisfyPrecondition(aspCtx.getAndExprStats())) {
-              updateStats(aspCtx.getAndExprStats(), newNumRows, true, op);
-            } else {
-              updateStats(aspCtx.getAndExprStats(), newNumRows, false, op);
-            }
+          }
+          newNumRows = evaluatedRowCount;
+          if (satisfyPrecondition(aspCtx.getAndExprStats())) {
+            updateStats(aspCtx.getAndExprStats(), newNumRows, true, op);
+          } else {
+            updateStats(aspCtx.getAndExprStats(), newNumRows, false, op);
           }
         } else if (udf instanceof GenericUDFOPOr) {
           // for OR condition independently compute and update stats.
           for (ExprNodeDesc child : genFunc.getChildren()) {
-            // early exit if OR evaluation yields more rows than input rows
-            if (evaluatedRowCount >= stats.getNumRows()) {
-              evaluatedRowCount = stats.getNumRows();
-            } else {
               newNumRows = StatsUtils.safeAdd(
-                  evaluateChildExpr(stats, child, aspCtx, neededCols, op, evaluatedRowCount),
+                  evaluateChildExpr(stats, child, aspCtx, neededCols, op, currNumRows),
                   newNumRows);
-              evaluatedRowCount = newNumRows;
-            }
+          }
+          if(newNumRows > currNumRows) {
+            newNumRows = currNumRows;
           }
         } else if (udf instanceof GenericUDFIn) {
           // for IN clause
-          newNumRows = evaluateInExpr(stats, pred, aspCtx, neededCols, op);
+          newNumRows = evaluateInExpr(stats, pred, currNumRows, aspCtx, neededCols, op);
         } else if (udf instanceof GenericUDFBetween) {
           // for BETWEEN clause
-          newNumRows = evaluateBetweenExpr(stats, pred, aspCtx, neededCols, op);
+          newNumRows = evaluateBetweenExpr(stats, pred, currNumRows, aspCtx, neededCols, op);
         } else if (udf instanceof GenericUDFOPNot) {
-          newNumRows = evaluateNotExpr(stats, pred, aspCtx, neededCols, op);
+          newNumRows = evaluateNotExpr(stats, pred, currNumRows, aspCtx, neededCols, op);
         } else if (udf instanceof GenericUDFOPNotNull) {
-          return evaluateNotNullExpr(stats, genFunc);
+          return evaluateNotNullExpr(stats, genFunc, currNumRows);
         } else {
           // single predicate condition
-          newNumRows = evaluateChildExpr(stats, pred, aspCtx, neededCols, op, evaluatedRowCount);
+          newNumRows = evaluateChildExpr(stats, pred, aspCtx, neededCols, op,currNumRows);
         }
       } else if (pred instanceof ExprNodeColumnDesc) {
 
@@ -415,10 +414,10 @@
protected long evaluateExpression(Statistics stats, ExprNodeDesc pred,
       return newNumRows;
     }
 
-    private long evaluateInExpr(Statistics stats, ExprNodeDesc pred, AnnotateStatsProcCtx aspCtx,
+    private long evaluateInExpr(Statistics stats, ExprNodeDesc pred, long currNumRows, AnnotateStatsProcCtx aspCtx,
             List<String> neededCols, Operator<?> op) throws SemanticException {
 
-      long numRows = stats.getNumRows();
+      long numRows = currNumRows;
 
       ExprNodeGenericFuncDesc fd = (ExprNodeGenericFuncDesc) pred;
 
@@ -505,7 +504,7 @@
private long evaluateInExpr(Statistics stats, ExprNodeDesc pred, AnnotateStatsPr
       return Math.round( (double) numRows * factor * inFactor);
     }
 
-    private long evaluateBetweenExpr(Statistics stats, ExprNodeDesc pred, AnnotateStatsProcCtx aspCtx,
+    private long evaluateBetweenExpr(Statistics stats, ExprNodeDesc pred, long currNumRows, AnnotateStatsProcCtx aspCtx,
             List<String> neededCols, Operator<?> op) throws SemanticException, CloneNotSupportedException {
       final ExprNodeGenericFuncDesc fd = (ExprNodeGenericFuncDesc) pred;
       final boolean invert = Boolean.TRUE.equals(
@@ -517,7 +516,7 @@
private long evaluateBetweenExpr(Statistics stats, ExprNodeDesc pred, AnnotateSt
       // Short circuit and return the current number of rows if this is a
       // synthetic predicate with dynamic values
       if (leftExpression instanceof ExprNodeDynamicValueDesc) {
-        return stats.getNumRows();
+        return currNumRows;
       }
 
       // We transform the BETWEEN clause to AND clause (with NOT on top in invert is true).
@@ -534,14 +533,14 @@
private long evaluateBetweenExpr(Statistics stats, ExprNodeDesc pred, AnnotateSt
           new GenericUDFOPNot(), Lists.newArrayList(newExpression));
       }
 
-      return evaluateExpression(stats, newExpression, aspCtx, neededCols, op, 0);
+      return evaluateExpression(stats, newExpression, aspCtx, neededCols, op, currNumRows);
     }
 
-    private long evaluateNotExpr(Statistics stats, ExprNodeDesc pred,
+    private long evaluateNotExpr(Statistics stats, ExprNodeDesc pred, long currNumRows,
         AnnotateStatsProcCtx aspCtx, List<String> neededCols, Operator<?> op)
         throws CloneNotSupportedException, SemanticException {
 
-      long numRows = stats.getNumRows();
+      long numRows = currNumRows;
 
       // if the evaluate yields true then pass all rows else pass 0 rows
       if (pred instanceof ExprNodeGenericFuncDesc) {
@@ -553,7 +552,7 @@
private long evaluateNotExpr(Statistics stats, ExprNodeDesc pred,
             long newNumRows = 0;
             for (ExprNodeDesc child : genFunc.getChildren()) {
               newNumRows = evaluateChildExpr(stats, child, aspCtx, neededCols,
-                  op, 0);
+                  op, numRows);
             }
             return numRows - newNumRows;
           } else if (leaf instanceof ExprNodeConstantDesc) {
@@ -585,9 +584,9 @@
private long evaluateNotExpr(Statistics stats, ExprNodeDesc pred,
       return numRows / 2;
     }
 
-    private long evaluateColEqualsNullExpr(Statistics stats, ExprNodeDesc pred) {
+    private long evaluateColEqualsNullExpr(Statistics stats, ExprNodeDesc pred, long currNumRows) {
 
-      long numRows = stats.getNumRows();
+      long numRows = currNumRows;
 
       if (pred instanceof ExprNodeGenericFuncDesc) {
 
@@ -609,9 +608,9 @@
private long evaluateColEqualsNullExpr(Statistics stats, ExprNodeDesc pred) {
       return numRows / 2;
     }
 
-    private long evaluateNotNullExpr(Statistics parentStats, ExprNodeGenericFuncDesc pred) {
+    private long evaluateNotNullExpr(Statistics parentStats, ExprNodeGenericFuncDesc pred, long currNumRows) {
       long noOfNulls = getMaxNulls(parentStats, pred);
-      long parentCardinality = parentStats.getNumRows();
+      long parentCardinality = currNumRows;
       long newPredCardinality = parentCardinality;
 
       if (parentCardinality > noOfNulls) {
@@ -661,8 +660,8 @@
private long getMaxNulls(Statistics stats, ExprNodeDesc pred) {
       return maxNoNulls;
     }
 
-    private long evaluateComparator(Statistics stats, ExprNodeGenericFuncDesc genFunc) {
-      long numRows = stats.getNumRows();
+    private long evaluateComparator(Statistics stats, ExprNodeGenericFuncDesc genFunc, long currNumRows) {
+      long numRows = currNumRows;
       GenericUDF udf = genFunc.getGenericUDF();
 
       ExprNodeColumnDesc columnDesc;
@@ -838,9 +837,9 @@
private long evaluateComparator(Statistics stats, ExprNodeGenericFuncDesc genFun
 
     private long evaluateChildExpr(Statistics stats, ExprNodeDesc child,
         AnnotateStatsProcCtx aspCtx, List<String> neededCols,
-        Operator<?> op, long evaluatedRowCount) throws CloneNotSupportedException, SemanticException {
+        Operator<?> op, long currNumRows) throws CloneNotSupportedException, SemanticException {
 
-      long numRows = stats.getNumRows();
+      long numRows = currNumRows;
 
       if (child instanceof ExprNodeGenericFuncDesc) {
 
@@ -917,15 +916,15 @@
private long evaluateChildExpr(Statistics stats, ExprNodeDesc child,
                 || udf instanceof GenericUDFOPEqualOrLessThan
                 || udf instanceof GenericUDFOPGreaterThan
                 || udf instanceof GenericUDFOPLessThan) {
-          return evaluateComparator(stats, genFunc);
+          return evaluateComparator(stats, genFunc, numRows);
         } else if (udf instanceof GenericUDFOPNotNull) {
-          return evaluateNotNullExpr(stats, genFunc);
+          return evaluateNotNullExpr(stats, genFunc, numRows);
         } else if (udf instanceof GenericUDFOPNull) {
-          return evaluateColEqualsNullExpr(stats, genFunc);
+          return evaluateColEqualsNullExpr(stats, genFunc, numRows);
         } else if (udf instanceof GenericUDFOPAnd || udf instanceof GenericUDFOPOr
                 || udf instanceof GenericUDFIn || udf instanceof GenericUDFBetween
                 || udf instanceof GenericUDFOPNot) {
-          return evaluateExpression(stats, genFunc, aspCtx, neededCols, op, evaluatedRowCount);
+          return evaluateExpression(stats, genFunc, aspCtx, neededCols, op, numRows);
         } else if (udf instanceof GenericUDFInBloomFilter) {
           if (genFunc.getChildren().get(1) instanceof ExprNodeDynamicValueDesc) {
             // Synthetic predicates from semijoin opt should not affect stats.
@@ -936,7 +935,7 @@
private long evaluateChildExpr(Statistics stats, ExprNodeDesc child,
         if (Boolean.FALSE.equals(((ExprNodeConstantDesc) child).getValue())) {
           return 0;
         } else {
-          return stats.getNumRows();
+          return numRows;
         }
       }
 
@@ -1584,7 +1583,7 @@
public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx procCtx,
           // evaluate filter expression and update statistics
           try {
             newNumRows = evaluateExpression(stats, pred,
-                aspCtx, jop.getSchema().getColumnNames(), jop, 0);
+                aspCtx, jop.getSchema().getColumnNames(), jop, stats.getNumRows());
           } catch (CloneNotSupportedException e) {
             throw new SemanticException(ErrorMsg.STATISTICS_CLONING_FAILED.getMsg());
           }
@@ -1673,7 +1672,7 @@
public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx procCtx,
           // evaluate filter expression and update statistics
           try {
             newNumRows = evaluateExpression(wcStats, pred,
-                aspCtx, jop.getSchema().getColumnNames(), jop, 0);
+                aspCtx, jop.getSchema().getColumnNames(), jop, wcStats.getNumRows());
           } catch (CloneNotSupportedException e) {
             throw new SemanticException(ErrorMsg.STATISTICS_CLONING_FAILED.getMsg());
           }
